define [
  'views/base/view'
  'meiomask'
  'lib/form_handlebars_helpers'
], (View) ->

  'use strict'

  class BaseFormView extends View

    # Override Attributtes
    # =============================================================

    successMessage    : 'Registro salvo'
    formSelector      : 'form'
    formEvent         : 'submit'

    # Aditional Attributtes
    # =============================================================
    firstFocus         : true
    formData           : {}
    validationRules    : null
    validationMessages : null
    validationGroups   : null

    # Override Methods
    # =============================================================

    initialize: (options={}) ->
      super

      _(@).extend options

      do @createLoader
      if @model and @model?.id and !@model?.fetched
        @model.fetch().always => do @render
      else
        do @render

    afterRender: ->
      @$form = @$el.find(@formSelector)

      super

      @$form.attr 'novalidate', 'novalidate'

      @setupValidator()
      @fillForm @model if @fillForm
      @$form.find(':input:first:visible').focus() if @firstFocus

    render: ->
      do @hideLoader
      super

    # Additional Methods
    # =============================================================

    # Faz o cache dos elementos do DOM que são manipulados durante a execução
    cacheDOMElements: ->
      @DOMElements =
        $btnSubmit : @$el.find 'button[type="submit"]'

    # Configurações de validação
    setupValidator: (settings={}) ->
      hasSettings = @validationRules or settings.rules
      return unless hasSettings

      @validatorSettings or= {}

      @validatorSettings.rules    = _.result @, 'validationRules'    if @validationRules
      @validatorSettings.messages = _.result @, 'validationMessages' if @validationMessages
      @validatorSettings.groups   = _.result @, 'validationGroups'   if @validationGroups

      _.extend @validatorSettings.rules    , settings.rules    if settings.rules
      _.extend @validatorSettings.messages , settings.messages if settings.messages
      _.extend @validatorSettings.groups   , settings.groups   if settings.groups

      if !@validator
        @validator = @$form.validate @validatorSettings
      else
        _.extend @validator.settings, @validatorSettings

    fillModel : (form) ->
    fillForm  : (model) ->

    # Muda o texto do botão de submit
    changeSubmitLabel: (label='Salvar') ->
      @DOMElements.$btnSubmit.text label if @DOMElements.$btnSubmit

    # Registra os eventos dos elementos do DOM
    registryDOMEvents: ->
      @delegate @formEvent, @formSelector, @submitHandler

    submitHandler: (event) ->
      event.preventDefault()
      event.stopPropagation()

      do @saveData

    # Salva os dados da model
    saveData: ->
      @modelUnbind 'change', @render

      @fillModel @$form

      @disableActions()

      promise = $.Deferred().done()
      if @model and @saveAsJSON
        promise = @model.saveAsJSON()
      else if @model
        promise = @model.save()

      promise.done   => @trigger 'model:saved'
      promise.fail   => @trigger 'model:notSaved'
      promise.always => @enableActions()

    dispose: ->
      super

      propertiesToReset = [
        'successMessage'
        'formSelector'
        'formEvent'
        'firstFocus'
        'formData'
        'validationRules'
        'validationMessages'
        'validationGroups'
      ]
      delete @[prop] for prop in propertiesToReset